﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Xproject.Util; 

namespace Core.WeiXin
{
    public class WXcommonHelper
    {
        public static string PostFormData(List<FormItem> list, string uri)
        {
            string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
            //请求 
            WebRequest req = WebRequest.Create(uri);
            req.Method = "POST";
            req.ContentType = "multipart/form-data; boundary=" + boundary;

            //组织表单数据 
            StringBuilder sb = new StringBuilder();
            foreach (FormItem item in list)
            {
                switch (item.ParamType)
                {
                    case ParamType.Text:
                        sb.Append("--" + boundary);
                        sb.Append("\r\n");
                        sb.Append("Content-Disposition: form-data; name=\"" + item.Name + "\"");
                        sb.Append("\r\n\r\n");
                        sb.Append(item.Value);
                        sb.Append("\r\n");
                        break;
                    case ParamType.File:
                        sb.Append("--" + boundary);
                        sb.Append("\r\n");
                        string filename = System.IO.Path.GetFileName(item.Value);
                        sb.Append("Content-Disposition: form-data; name=\"media\"; filename=\"" + filename + "\"");
                        sb.Append("\r\n");
                        sb.Append("Content-Type: image/jpeg");
                        sb.Append("\r\n\r\n");
                        break;
                }
            }

            string head = sb.ToString();
            LogHelper.WriteInfoLog("uploadImage head:" + head + "\r\n");           
            //post字节总长度
            long length = 0;
            byte[] form_data = Encoding.UTF8.GetBytes(head);
            //结尾 
            byte[] foot_data = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
            List<FormItem> fileList = list.Where(f => f.ParamType == ParamType.File).ToList();
            length = form_data.Length + foot_data.Length;
            foreach (FormItem fi in fileList)
            {
                FileStream fileStream = new FileStream(fi.Value, FileMode.Open, FileAccess.Read);
                length += fileStream.Length;
                fileStream.Close();
                fileStream.Dispose();
            }
            req.ContentLength = length;

            Stream requestStream = req.GetRequestStream();
            //发送表单参数 
            requestStream.Write(form_data, 0, form_data.Length);

            foreach (FormItem fd in fileList)
            {
                FileStream fileStream = new FileStream(fd.Value, FileMode.Open, FileAccess.Read);
                //文件内容 
                byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
                int bytesRead = 0;
                while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    requestStream.Write(buffer, 0, bytesRead);
                //结尾 
                fileStream.Close();
                fileStream.Dispose();
                requestStream.Write(foot_data, 0, foot_data.Length);
                requestStream.Flush();
            }
            requestStream.Close();
            requestStream.Dispose();

            //响应 
            WebResponse pos = req.GetResponse();
            StreamReader sr = new StreamReader(pos.GetResponseStream(), Encoding.UTF8);
            string html = sr.ReadToEnd().Trim();
            sr.Close();

            if (pos != null)
            {
                pos.Close();
                pos = null;
            }

            if (req != null)
            {
                req = null;
            }
            return html;
        }


        public static string uploadImage2(string userId, string userName, string userHeadUrl)
        {
            string imageId = "";
            WeiXinModel.TokedataDataModel token = WeiXinHelper.GetToken();
            string posturl = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}";
            LogHelper.WriteInfoLog("uploadImage2 posturl:" + posturl + "\r\n");           

            posturl = string.Format(posturl, token.access_token, "image");

            string qrcodeUrlLink = GetQrCodeUrl(userId);
            CreateUserQRCodeImage2(userId, userName, userHeadUrl, qrcodeUrlLink, 0, 1);

            string filePath = HttpContext.Current.Server.MapPath("~/Content/Images/QRCode/" + userId + ".jpg");

            string content = "";             
            List<FormItem> list = new List<FormItem>();
            list.Add(new FormItem() { Name = "media", ParamType = ParamType.File, Value = filePath });
            content = PostFormData(list, posturl);
            if (string.IsNullOrEmpty(content)) return imageId;
            LogHelper.WriteInfoLog("uploadImage2 PostPage:" + content + "\r\n");
                      
            UploadImageResult imageReturnMessage = LitJson.JsonMapper.ToObject<UploadImageResult>(content);
            if (!string.IsNullOrEmpty(imageReturnMessage.media_id))
            {
                imageId = imageReturnMessage.media_id;
            }
            else
            {
                imageId = "xxx";
            }
            return imageId;
        }


        private static string GetQrCodeUrl(string userId)
        {
            WeiXinModel.TokedataDataModel token = WeiXinHelper.GetToken();
            var url = string.Format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}", token.access_token);
            var postStr = "{\"action_name\": \"QR_LIMIT_STR_SCENE\",\"action_info\":{\"scene\":{\"scene_str\":\"" + userId + "\"}}}";

            var resp = HttpService.CreateHttpRequest(url, postStr, 30, "POST");

            LogHelper.WriteInfoLog("GetQrCodeUrl resp= " + resp);
            


            if (string.IsNullOrEmpty(resp))
                return "生成二维码失败";
            var json = LitJson.JsonMapper.ToObject<Dictionary<string, string>>(resp);
            if (json.ContainsKey("ticket"))
                return string.Format("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}", json["ticket"]);
            else
            {
                return "生成二维码失败，不含ticket";
            }
        }

        static void CreateUserQRCodeImage2(string userId, string userName, string userHeadUrl, string linkUrl, int curCreateCount, int errMaxCount)
        {
            if (curCreateCount > errMaxCount) return;
            string folderPath = HttpContext.Current.Server.MapPath("~/Content/Images/QRCode/");                             
            string backgroundFileName = HttpContext.Current.Server.MapPath("~/wxshop/images/erm_QRCode.jpg");
            QRcodeHelper.Create_CodeImagesWithBackground(linkUrl, folderPath,  userId + ".jpg", backgroundFileName);            
        }

        public static Image GetUserHeadImage2(string userHeadUrl)
        {
            Image image = null;

            string imagePath = "~/Content/Images/QRCode/" + Guid.NewGuid().ToString("N") + ".jpg";
            string filepath = HttpContext.Current.Server.MapPath(imagePath);
            try
            {
                if (!Directory.Exists(Path.GetDirectoryName(filepath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(filepath));
                }
                WebClient mywebclient = new WebClient();

                if (string.IsNullOrEmpty(userHeadUrl.Trim()))
                {
                    filepath = HttpContext.Current.Server.MapPath("~/Content/Images/QRCode/erm_QRCode.jpg");
                    image = Image.FromFile(filepath);
                    Image cloneImage = new Bitmap(image);
                    image.Dispose();
                    image = cloneImage;
                }
                else
                {
                    mywebclient.DownloadFile(userHeadUrl, filepath);
                    image = Image.FromFile(filepath);
                    Image cloneImage = new Bitmap(image);
                    image.Dispose();
                    image = cloneImage;
                    if (File.Exists(filepath))
                    {
                        File.Delete(filepath);
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteErrorLog("生成二维码 ，下载头像失败！" + ex.Message,ex);                 
            }
            return image;
        }


        public class FormItem
        {
            public string Name { get; set; }

            public ParamType ParamType { get; set; }

            public string Value { get; set; }
        }

        public enum ParamType
        {
            ///
            /// 文本类型
            ///
            Text,

            ///
            /// 文件路径，需要全路径（例：C:\A.JPG)
            ///
            File
        }
        private struct UploadImageResult
        {
            public object type { get; set; }
            public string media_id { get; set; }
            public int created_at { get; set; }

            public int errcode { get; set; }
            public string errmsg { get; set; }

        }

    }


}
